package com.qumitech.visualnovel.controller.rest;


import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.qumitech.visualnovel.component.util.LocationUtil;
import com.qumitech.visualnovel.console.excel.ExportExcel;
import com.qumitech.visualnovel.console.excel.StateField;
import com.qumitech.visualnovel.console.excel.UnitField;
import com.qumitech.visualnovel.model.common.BaseRsp;
import com.qumitech.visualnovel.model.common.BaseResponse;
import com.qumitech.visualnovel.model.dto.AccountInfoQueryDTO;
import com.qumitech.visualnovel.model.dto.BookReadQueryDTO;
import com.qumitech.visualnovel.controller.vo.player.AccountForbiddenVo;
import com.qumitech.visualnovel.controller.vo.player.AccountPropertyVo;
import com.qumitech.visualnovel.controller.vo.player.UserResetRecordVO;
import com.qumitech.visualnovel.controller.vo.player.UserResetVO;
import com.qumitech.visualnovel.model.dao.console.AccountLogin;
import com.qumitech.visualnovel.model.dao.console.AccountRegister;
import com.qumitech.visualnovel.service.forbidden.UserForbiddenService;
import com.qumitech.visualnovel.service.player.PlayerInfoService;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

@RestController
@RequestMapping("/api/accountInfo")
public class PlayerInfoController {

    @Autowired
    private PlayerInfoService playerInfoService;

    @Autowired
    private UserForbiddenService userForbiddenService;

    @Autowired
    private LocationUtil locationUtil;

    @RequiresPermissions("accountList:view")
    @RequestMapping(value = "/accountList", method = RequestMethod.GET)
    @ExportExcel(itemKeys = {"uid","presentId","userName","grade","score","haiCoin","diamond","rechargeSum","incomeSum","withdrawableSum","phoneNum","signature","registerTime"},
            itemNames = {"内部ID","显示ID","昵称","等级","积分","嗨币","钻石","累计充值(元)","总收益(元)","可提现余额(元)","手机号","签名","创建时间"},
            listKey = "items",
            unitFields = {@UnitField(key="rechargeSum", unit = 100), @UnitField(key="incomeSum", unit=10000), @UnitField(key="withdrawableSum", unit = 10000)})
    public JSONObject accountList(AccountInfoQueryDTO param){
        return playerInfoService.getAccountList(param);
    }

    @RequiresPermissions("accountList:view")
    @RequestMapping(value = "/accountDetail", method = RequestMethod.GET)
    public JSONObject accountDetail(@RequestParam(value="accountId") String accountId)
    {
        return playerInfoService.getAccountDetail(accountId);
    }

    @RequestMapping(value = "/location/options", method = RequestMethod.GET)
    public JSONObject accountLocationOptions()
    {
        return playerInfoService.accountLocationOptions();
    }

    @RequiresPermissions("accountList:view")
    @RequestMapping(value = "/accountPreview", method = RequestMethod.GET)
    public JSONObject accountPreview(@RequestParam(value="accountId") String accountId)
    {
        return playerInfoService.getAccountPreview(accountId);
    }

    @RequiresPermissions("accountList:change")
    @RequestMapping(value = "/update", method = RequestMethod.POST)
    public JSONObject accountUpdate(@RequestBody AccountPropertyVo accountPropertyVo)
    {
        return playerInfoService.accountUpdate(accountPropertyVo);
    }

    @RequiresPermissions("accountList:change")
    @RequestMapping(value = "/createVoiceRoom", method = RequestMethod.POST)
    public JSONObject createVoiceRoom(@RequestBody JSONObject param)
    {
        return playerInfoService.createVoiceRoom(param.getString("uid"));
    }

    @RequiresPermissions("accountList:change")
    @RequestMapping(value = "/addForbidden", method = RequestMethod.POST)
    public JSONObject addForbidden(@RequestBody AccountForbiddenVo accountForbiddenVo)
    {
        return playerInfoService.accountForbiddenAdd(accountForbiddenVo);
    }

    @RequiresPermissions("accountList:change")
    @RequestMapping(value = "/delForbidden", method = RequestMethod.POST)
    public JSONObject delForbidden(@RequestBody AccountForbiddenVo accountForbiddenVo)
    {
        return playerInfoService.accountForbiddenDel(accountForbiddenVo.getForbiddenId());
    }

    @RequiresPermissions("rewardList:view")
    @RequestMapping(value = "/rewardList", method = RequestMethod.GET)
    public JSONObject getRewardList(@RequestParam(value="appId",required=false) String appId,
                                  @RequestParam(value="startTime") String startTime,
                                  @RequestParam(value="endTime") String endTime,
                                  @RequestParam(value="offset", required=false, defaultValue="0") int offset,
                                  @RequestParam(value="limit", required=false, defaultValue="20") int limit)
    {
        return playerInfoService.getRewardList(appId, startTime, endTime, offset, limit);
    }

    @RequiresPermissions("accountList:view")
    @RequestMapping(value = "/accountLoginDetail", method = RequestMethod.GET)
    public JSONObject accountLoginDetail(@RequestParam(value="accountId",required=false) Integer accountId,
                                         @RequestParam(value="startTime",required=false) String startTime,
                                         @RequestParam(value="endTime",required=false) String endTime,
                                         @RequestParam(value="appId",required=false) String appId,
                                         @RequestParam(value="offset", required=false, defaultValue="0") int offset,
                                         @RequestParam(value="limit", required=false, defaultValue="20") int limit,
                                         @RequestParam(value="orderType", required=false, defaultValue="DESC") String orderType,
                                         @RequestParam(value="orderBy", required=false, defaultValue="record_time") String orderBy)
    {

        List<AccountLogin> accountDeviceList = playerInfoService.getAccountLoginList(accountId, startTime, endTime, appId, offset, limit, orderBy, orderType);
        JSONObject data = new JSONObject();
        JSONArray dataItems = new JSONArray();
        data.put("count",playerInfoService.getAccountLoginCount(accountId, startTime, endTime, appId));
        data.put("items", dataItems);
        Set<String> ipSet = new HashSet<>();
        Set<String> deviceSet = new HashSet<>();
        if(accountDeviceList!=null)
        {
            for(AccountLogin accountLogin: accountDeviceList)
            {
                JSONObject accountDeviceItem = new JSONObject();
                accountDeviceItem.put("clientIp", accountLogin.getClientIp());
                accountDeviceItem.put("clientIpForbiddenStatus", 0); //默认没有封
                accountDeviceItem.put("deviceId", accountLogin.getDeviceId());
                accountDeviceItem.put("deviceIdForbiddenStatus", 0); //默认没有封
                accountDeviceItem.put("deviceImei", accountLogin.getDeviceImei());
                accountDeviceItem.put("deviceMac", accountLogin.getDeviceMac());
                accountDeviceItem.put("appVersion", accountLogin.getAppVersion());
                accountDeviceItem.put("location", accountLogin.getLocation());
                accountDeviceItem.put("gameType", accountLogin.getGameType());
                accountDeviceItem.put("channel", accountLogin.getAppChannel());
                accountDeviceItem.put("recordTime", accountLogin.getRecordTime());
                accountDeviceItem.put("startAppChannel", accountLogin.getStartAppChannel());
                accountDeviceItem.put("loginType", accountLogin.getLoginTypeName());
                ipSet.add(accountLogin.getClientIp());
                deviceSet.add(accountLogin.getDeviceId());
                dataItems.add(accountDeviceItem);
            }
        }
        ipSet = userForbiddenService.findForbiddenIp(ipSet);
        deviceSet = userForbiddenService.findForbiddenDeviceId(deviceSet);
        for(int i=0;i<dataItems.size();i++)
        {
            JSONObject accountDeviceItem = dataItems.getJSONObject(i);
            if (ipSet.contains(accountDeviceItem.getString("clientIp")))
            {
                accountDeviceItem.put("clientIpForbiddenStatus", 1);
            }
            if (deviceSet.contains(accountDeviceItem.getString("deviceId")))
            {
                accountDeviceItem.put("deviceIdForbiddenStatus", 1);
            }
        }
        BaseResponse results = new BaseResponse(data);
        return results;
    }

    @RequiresPermissions("accountList:view")
    @RequestMapping(value = "/accountRegisterDetail", method = RequestMethod.GET)
    public JSONObject accountRegisterDetail(@RequestParam(value="accountId", required=false) Integer accountId,
                                            @RequestParam(value="startTime",required=false) String startTime,
                                            @RequestParam(value="endTime",required=false) String endTime,
                                            @RequestParam(value="appId",required=false) String appId,
                                            @RequestParam(value="offset", required=false, defaultValue="0") int offset,
                                            @RequestParam(value="limit", required=false, defaultValue="20") int limit,
                                            @RequestParam(value="orderType", required=false, defaultValue="DESC") String orderType,
                                            @RequestParam(value="orderBy", required=false, defaultValue="record_time") String orderBy)
    {
        List <AccountRegister> accountRegisterList = playerInfoService.getAccountRegisterList(accountId, startTime, endTime, appId, offset, limit, orderBy, orderType);
        JSONObject data = new JSONObject();
        JSONArray dataItems = new JSONArray();
        data.put("count",playerInfoService.getAccountRegisterCount(accountId, startTime, endTime, appId));
        data.put("items", dataItems);
        if(accountRegisterList!=null)
        {
            for(AccountRegister accountUid: accountRegisterList)
            {
                JSONObject accountUidItem = new JSONObject();
                accountUidItem.put("clientIp", accountUid.getClientIp());
                accountUidItem.put("deviceId", accountUid.getDeviceId());
                accountUidItem.put("deviceMac", accountUid.getDeviceMac());
                accountUidItem.put("deviceImei", accountUid.getDeviceImei());
                accountUidItem.put("channel", accountUid.getAppChannel());
                accountUidItem.put("appName", accountUid.getAppName());
                accountUidItem.put("recordTime", accountUid.getRecordTime());
                accountUidItem.put("location", accountUid.getLocation());
                dataItems.add(accountUidItem);
            }
        }
        BaseResponse results = new BaseResponse(data);
        return results;
    }

    @GetMapping(value="/ip-location")
    public JSONObject ipToLocation(@RequestParam(value = "ip") String ip) {

        JSONObject data = new JSONObject();
        data.put("location", locationUtil.getLocationAddressByIP(ip));
        BaseResponse results = new BaseResponse(data);
        return results;
    }

    @RequiresPermissions("accountList:view")
    @GetMapping(value = "/{uid}/reset")
    public BaseRsp getUserReset(@PathVariable(value="uid") Long uid)
    {
        return playerInfoService.getUserReset(uid);
    }

    @RequiresPermissions("accountList:change")
    @PutMapping(value = "/{uid}/reset")
    public BaseRsp resetUserReset(@PathVariable(value="uid") Long uid,
                                @RequestBody UserResetVO userResetVO)
    {
        return playerInfoService.resetUserReset(userResetVO);
    }

    @RequiresPermissions("accountList:view")
    @GetMapping(value = "/reset_record")
    public BaseRsp getResetRecords(UserResetRecordVO resetRecordVO)
    {
        return playerInfoService.getResetRecords(resetRecordVO);
    }

    @GetMapping("/guard")
    public BaseRsp listGuard(@RequestParam(value="offset", required=false, defaultValue="0") int offset,
                                      @RequestParam(value="limit", required=false, defaultValue="20") int limit,
                                      @RequestParam(value="fromId", required=false) Long fromId,
                                      @RequestParam(value="toId", required=false) Long toId,
                                      @RequestParam(value="startTime", required=false) String startTime,
                                      @RequestParam(value="endTime", required=false) String endTime,
                                      @RequestParam(value="orderType", required=false, defaultValue="DESC") String orderType,
                                      @RequestParam(value="orderBy", required=false, defaultValue="create_time") String orderBy) {
        return playerInfoService.listGuard(fromId, toId, startTime, endTime, orderBy, orderType, offset, limit);
    }

    @GetMapping("/noble")
    public BaseRsp listNoble(@RequestParam(value="offset", required=false, defaultValue="0") int offset,
                                       @RequestParam(value="limit", required=false, defaultValue="20") int limit,
                                       @RequestParam(value="uid", required=false) Long uid,
                                       @RequestParam(value="level", required=false) Long level,
                                       @RequestParam(value="startTime", required=false) String startTime,
                                       @RequestParam(value="endTime", required=false) String endTime,
                                       @RequestParam(value="orderType", required=false, defaultValue="DESC") String orderType,
                                       @RequestParam(value="orderBy", required=false, defaultValue="create_time") String orderBy) {
        return playerInfoService.listNoble(uid, level, startTime, endTime, orderBy, orderType, offset, limit);
    }

    @GetMapping("/noble/cfg")
    public BaseRsp getNobleConfig() {
        return playerInfoService.getNobleConfig();
    }

    @RequiresPermissions("accountList:view")
    @GetMapping(value = "/bookRead/list")
    public JSONObject bookReadList(BookReadQueryDTO param) {
        return playerInfoService.bookReadList(param);
    }
}
